﻿using IPluginInterface;
using Qting.AOI.Serialize;
using System;
using System.IO;
using System.Reflection;

namespace IPluginInterface
{
    public class AssemblyDynamicLoader
    {
        /// <summary>
        /// 接口回调函数
        /// </summary>
        /// <param name="args"></param>
        public delegate void PluginCallback(Method method, params object[] args);
        public string PluginName { get; set; }
        /// <summary>
        /// 获取插件内名称
        /// </summary>
        public string PluginTag { get { return remoteLoader.PluginName(); } }
        /// <summary>
        /// 获取插件版本
        /// </summary>
        public Version PluginVersion { get { return remoteLoader.PluginVersion(); } }
        /// <summary>
        /// 插件的描述
        /// </summary>
        public string PluginDescription { get { return remoteLoader.PluginDescription(); } }

        private AppDomain appDomain;
        private RemoteLoader remoteLoader;

        public AssemblyDynamicLoader(string pluginName)
        {
            PluginName = pluginName;
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationName = pluginName;
            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            setup.PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            setup.CachePath = setup.ApplicationBase;
            setup.ShadowCopyFiles = "false";//"true";
            setup.ShadowCopyDirectories = setup.ApplicationBase;
            //AppDomain.CurrentDomain.SetShadowCopyFiles();

            this.appDomain = AppDomain.CreateDomain("app_" + pluginName, null, setup);
            String name = Assembly.GetExecutingAssembly().GetName().FullName;
            this.remoteLoader = (RemoteLoader)this.appDomain.CreateInstanceAndUnwrap(name, typeof(RemoteLoader).FullName);
        }

     
        /// <summary>
        /// 加载程序集
        /// </summary>
        /// <param name="assemblyFile"></param>
        public void LoadAssembly(string assemblyFile, string pluginName)
        {
            remoteLoader.LoadAssembly(assemblyFile, pluginName);
        }

        /// <summary>
        /// 创建对象实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public T GetInstance<T>(string typeName) where T : class
        {
            if (remoteLoader == null) return null;
            return remoteLoader.GetInstance<T>(typeName);
        }

        /// <summary>
        /// 执行类型方法
        /// </summary>
        /// <param name="typeName"></param>
        /// <param name="methodName"></param>
        /// <returns></returns>
        public object ExecuteMethod(string typeName, Method method,ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            return remoteLoader.ExecuteMethod(typeName, method,ref aoiPcbs, bDual, args);
        }

        /// <summary>
        /// 卸载应用程序域
        /// </summary>
        public void Unload()
        {
            try
            {
                if (appDomain == null) return;
                AppDomain.Unload(this.appDomain);
                this.appDomain = null;
                this.remoteLoader = null;
            }
            catch (CannotUnloadAppDomainException ex)
            {
                throw ex;
            }
        }

        public Assembly[] GetAssemblies()
        {
            return this.appDomain.GetAssemblies();
        }
    }
}
